<template>
  <!-- <div>
    <div>
      <button @click="recOpen">打开录音,请求权限</button>
      | <button @click="recStart">开始录音</button>
      <button @click="recStop">结束录音</button>
      | <button @click="recPlay">本地试听</button>
    </div>
    <div style="padding-top: 5px">
      <div style="border: 1px solid #ccc; display: inline-block; vertical-align: bottom">
        <div style="height: 100px; width: 300px" ref="recwave"></div>
      </div>
    </div>
  </div> -->
  <div style="padding: 20px">
    <h3 class="title">
      <span>当前谈案室：{{ roomNum }}号谈案室</span>
      <el-button type="primary" icon="el-icon-refresh-right" size="mini" @click="onRefresh">数据刷新</el-button>
    </h3>

    <div class="select-visit">
      <el-select v-model="visit_id" placeholder="请选择上门数据" style="width: 100%" :disabled="recordStatus == 1">
        <el-option v-for="item in visitList" :key="item.id" :label="`${item.selectText}`" :value="item.id"> </el-option>
      </el-select>
      <div class="visit-desc" v-if="visit_id">
        <div class="visit-item">
          <div class="label">访客姓名：</div>
          <div class="value">{{ selectVisit.name }}</div>
        </div>
        <div class="visit-item">
          <div class="label">访客手机：</div>
          <div class="value">{{ selectVisit.mobile }}</div>
        </div>
        <div class="visit-item">
          <div class="label">上门时间：</div>
          <div class="value">{{ selectVisit.confirm_time }}</div>
        </div>
        <div class="visit-item">
          <div class="label">大致案情：</div>
          <div class="value">{{ selectVisit.remark }}</div>
        </div>
      </div>
    </div>
    <div class="select-user">
      <el-select
        v-model="user_id"
        placeholder="请选择谈案顾问"
        filterable
        style="width: 100%"
        :disabled="recordStatus == 1"
      >
        <el-option v-for="item in userList" :key="item.id" :label="item.realname" :value="item.id"> </el-option>
      </el-select>
    </div>
    <div style="padding-top: 5px">
      <div style="border: 1px solid #ccc; display: inline-block; vertical-align: bottom; width: 100%">
        <div style="height: 100px; width: 100%" ref="recwave"></div>
      </div>
    </div>
    <el-progress
      :percentage="progress"
      status="success"
      :text-inside="true"
      :stroke-width="20"
      style="margin-top: 10px"
      v-if="isUpload"
    ></el-progress>

    <div class="footer-box" v-if="visit_id && user_id">
      <div class="time-box">
        {{ timeHandle(recordTime) }}
      </div>
      <div class="button-box">
        <div class="cancel-box" v-if="recordStatus != 0" @click="handleDestroy()">
          <i class="el-icon-close" style="font-size: 30px"></i>
          <div>取消</div>
        </div>
        <div class="play-box" @click="handleClick">
          <i
            class="el-icon-video-play"
            style="font-size: 30px; color: red"
            v-if="recordStatus == 0 || recordStatus == 2 || recordStatus == 3"
          ></i>
          <i class="el-icon-video-pause" style="font-size: 30px; color: red" v-if="recordStatus == 1"></i>
        </div>
        <div class="confirm-box" v-if="recordStatus != 0" @click="handleComplete">
          <i class="el-icon-check" style="font-size: 30px"></i>
          <div>完成录音</div>
        </div>
      </div>
    </div>
  </div>
</template>
<script>
//必须引入的核心
import Recorder from 'recorder-core'
//引入mp3格式支持文件；如果需要多个格式支持，把这些格式的编码引擎js文件放到后面统统引入进来即可
import 'recorder-core/src/engine/mp3'
import 'recorder-core/src/engine/mp3-engine'
//录制wav格式的用这一句就行
//import 'recorder-core/src/engine/wav'
//可选的插件支持项，这个是波形可视化插件
import 'recorder-core/src/extensions/waveview'
//ts import 提示：npm包内已自带了.d.ts声明文件（不过是any类型）

// 阿里云oss上传插件
import OSS from 'ali-oss'
import moment from 'moment'

// eslint-disable-next-line
import { todayList, getUser, saveRecord, setStart } from '@/api/common.js'

export default {
  data() {
    return {
      rec: null,
      recordTime: 0, // 录制时间
      recordTimeId: null,
      src: '',
      companyId: localStorage.getItem('companyId'),
      roomNum: localStorage.getItem('roomNum'),

      // 上门登记数据
      visitList: [],
      visit_id: '',
      selectVisit: {},
      // 谈案顾问数据
      oldUserList: [],
      userList: [],
      user_id: '',
      selectUser: {},

      recordStatus: 0,
      isUpload: false,
      progress: 0 // 上传进度
    }
  },
  mounted() {
    // 若未设置公司
    if (!localStorage.getItem('companyId')) {
      this.$router.replace('/company')
      return
    }
    // 若未设置谈案室
    if (!localStorage.getItem('roomNum')) {
      this.$router.replace('/room')
      return
    }

    this.getUser()
    this.getList()

    this.recOpen()
  },
  methods: {
    // 获取上门数据
    getList() {
      this.$loading()
      todayList({
        room: this.roomNum,
        str_id: this.companyId
      })
        .then(res => {
          this.visitList = res.data
          if (res.data.length == 1) {
            // 只有一条数据默认选中
            this.selectVisit = res.data[0]
            this.visit_id = res.data[0].id
          }
        })
        .finally(() => {
          this.$loading().close()
        })
    },
    // 获取谈案顾问列表
    getUser() {
      getUser({
        str_id: this.companyId
      }).then(res => {
        this.oldUserList = res.data
        this.userList = res.data
      })
    },
    // 初始化录音
    recOpen() {
      //创建录音对象
      this.rec = Recorder({
        type: 'mp3', //录音格式，可以换成wav等其他格式
        sampleRate: 16000, //录音的采样率，越大细节越丰富越细腻
        bitRate: 16, //录音的比特率，越大音质越好
        // eslint-disable-next-line
        onProcess: (buffers, powerLevel, bufferDuration, bufferSampleRate, newBufferIdx, asyncEnd) => {
          //录音实时回调，大约1秒调用12次本回调
          //可实时绘制波形，实时上传（发送）数据
          if (this.wave) this.wave.input(buffers[buffers.length - 1], powerLevel, bufferSampleRate)
        }
      })

      //打开录音，获得权限
      this.rec.open(
        () => {
          console.log('录音已打开')
          if (this.$refs.recwave) {
            //创建音频可视化图形绘制对象
            this.wave = Recorder.WaveView({ elem: this.$refs.recwave })
          }
        },
        (msg, isUserNotAllow) => {
          //用户拒绝了录音权限，或者浏览器不支持录音
          // console.log((isUserNotAllow ? 'UserNotAllow，' : '') + '无法录音:' + msg)
          this.$message({
            message: (isUserNotAllow ? 'UserNotAllow，' : '') + '无法录音:' + msg,
            type: 'error'
          })
        }
      )
    },
    handleClick() {
      if (this.isUpload) {
        this.$message({
          message: '正在上传录音，请稍后',
          type: 'error'
        })
        return
      }
      if (this.recordStatus == 0) {
        // 开始录音
        this.handleStart()
      } else if (this.recordStatus == 1) {
        // 暂停录音
        this.handlePause()
      } else if (this.recordStatus == 2) {
        // 继续录音
        this.handleResume()
      }
    },
    onRefresh() {
      if (this.isUpload) {
        this.$message({
          message: '正在上传录音，请稍后',
          type: 'error'
        })
        return
      }
      if (this.recordStatus != 0) {
        this.handleDestroy('正在录音刷新将重置当前页面，您是否了解清楚？')
      } else {
        this.getList()
        this.getUser()
      }
    },
    // 开始录音
    handleStart() {
      if (!this.rec) {
        console.error('未打开录音')
        this.$message({
          message: '未打开录音',
          type: 'error'
        })
        return
        // this.recOpen()
      }
      this.$loading({
        lock: true,
        text: '设置开始谈案，录音功能启动中'
      })
      setStart({
        user_id: this.user_id,
        visit_id: this.visit_id
      })
        .then(res => {
          if (res.code == 200) {
            console.log('已开始录音')
            this.rec.start() // 开始录音
            this.recordTimeId = setInterval(() => {
              // 录音时间
              this.recordTime++
            }, 1000)
            this.recordStatus = 1 // 录音中
          } else {
            this.$message({
              message: res.msg || '谈案状态设置失败',
              type: 'error'
            })
          }
        })
        .finally(() => {
          this.$loading().close()
        })
      // this.rec.start()
      // this.recordStatus = 1 // 录音中
      // this.recordTimeId = setInterval(() => {
      //   // 录音时间
      //   this.recordTime++
      // }, 1000)
    },
    // 暂停录音
    handlePause() {
      if (!this.rec) {
        this.$message({
          message: '未打开录音',
          type: 'error'
        })
        return
      }
      this.rec.pause()
      this.recordStatus = 2
      // 暂停计时器
      clearInterval(this.recordTimeId)
    },
    // 继续录音
    handleResume() {
      if (!this.rec) {
        this.$message({
          message: '未打开录音',
          type: 'error'
        })
        return
      }
      this.rec.resume()
      this.recordStatus = 1
      this.recordTimeId = setInterval(() => {
        // 录音时间
        this.recordTime++
      }, 1000)
    },
    // 关闭释放录音资源
    handleDestroy(msg = '') {
      if (this.isUpload) {
        this.$message({
          message: '正在上传录音，请稍后',
          type: 'error'
        })
        return
      }
      if (msg == '') msg = '取消录音将重置当前页面，您是否了解清楚？'
      this.$confirm(msg, '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      })
        .then(() => {
          console.log('销毁实例')
          // 销毁实例
          this.rec.close()
          // 销毁计时器
          clearInterval(this.recordTimeId)
          // 数据重置
          Object.assign(this.$data, this.$options.data.call(this))
          this.getUser()
          this.getList()
        })
        .catch(() => {
          // on cancel
        })
    },
    handleComplete() {
      if (this.isUpload) {
        this.$message({
          message: '正在上传录音，请稍后',
          type: 'error'
        })
        return
      }
      if (!this.rec) {
        // console.error('未打开录音')
        this.$message({
          message: '未打开录音',
          type: 'error'
        })
        return
      }
      this.rec.stop(
        (blob, duration) => {
          this.recordStatus = 3
          // 销毁计时器
          clearInterval(this.recordTimeId)
          //blob就是我们要的录音文件对象，可以上传，或者本地播放
          this.recBlob = blob
          //简单利用URL生成本地文件地址，此地址只能本地使用，比如赋值给audio.src进行播放，赋值给a.href然后a.click()进行下载（a需提供download="xxx.mp3"属性）
          var localUrl = window.URL.createObjectURL(blob)
          this.src = localUrl
          console.log('录音成功', blob, localUrl, '时长:' + duration + 'ms')

          this.uploadRecord(blob) //把blob文件上传到服务器
          // this.rec.close() //关闭录音，释放录音资源
          // this.rec = null
        },
        err => {
          console.error('结束录音出错：' + err)
          this.rec.close() //关闭录音，释放录音资源
          this.rec = null
        }
      )
    },
    uploadRecord(blob) {
      this.isUpload = true
      // 配置你的OSS客户端
      const client = new OSS({
        region: 'oss-cn-beijing',
        accessKeyId: 'LTAI5t7nvBiE1bBDAQpXoS4j',
        accessKeySecret: 'Ig1kgCV46TJ5FBwWPGYZKgZGqGZdJW',
        bucket: 'lianghe'
      })
      let fileName = 'RecordApp/' + moment().format('YYYYMMDD') + '/' + this.generateNonceStr(32) + '.mp3' //文件名

      // 上传Blob文件
      client
        .multipartUpload(fileName, blob, {
          // eslint-disable-next-line
          progress: function (percent, checkpoint) {
            this.progress = percent * 100
            console.log('上传进度', percent * 100, '%')
          }.bind(this)
        })
        .then(({ res }) => {
          console.log('File uploaded successfully', res.statusCode)

          var params = {
            types: 1,
            visit_id: this.visit_id,
            record_name: `${moment().format('YYYYMMDD')}-${this.roomNum}号谈案室-${this.selectVisit.mobile}.mp3`,
            record_path: fileName,
            room_num: this.roomNum,
            df_phone: this.selectVisit.mobile,
            user_id: this.user_id
          }
          this.saveRecord(params)
        })
        .catch(err => {
          console.error('File upload failed', err)
          this.$message({
            message: '录音上传失败' + err,
            type: 'error'
          })
        })
    },

    handlePlay() {
      //本地播放录音试听，可以直接用URL把blob转换成本地播放地址，用audio进行播放
      var localUrl = URL.createObjectURL(this.recBlob)
      var audio = document.createElement('audio')
      audio.controls = true
      document.body.appendChild(audio)
      audio.src = localUrl
      audio.play() //这样就能播放了

      //注意不用了时需要revokeObjectURL，否则霸占内存
      setTimeout(function () {
        URL.revokeObjectURL(audio.src)
      }, 5000)
    },
    // 随机码生成
    generateNonceStr(length = 16) {
      const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
      const maxPos = chars.length
      let nonceStr = ''
      for (let i = 0; i < length; i++) {
        nonceStr += chars.charAt(Math.floor(Math.random() * maxPos))
      }
      return nonceStr
    },
    // 时间处理
    timeHandle(e) {
      let time = e
      let ms = time * 1000 // 1485000毫秒
      let date = new Date(ms)

      // 注意这里是使用的getUTCHours()方法，转换成UTC(协调世界时)时间的小时
      let hour = date.getUTCHours()
      // let hour = date.getHours(); 如果直接使用getHours()方法，则得到的时分秒格式会多出来8个小时（在国内开发基本都是使用的是东八区时间），getHours()方法会把当前的时区给加上。
      let minute = date.getMinutes()
      let second = date.getSeconds()

      let formatTime = `${hour.toString().padStart(2, '0')}:${minute.toString().padStart(2, '0')}:${second
        .toString()
        .padStart(2, '0')}`

      // console.log(formatTime) // "00:24:45"
      // this.formatTime = formatTime
      return formatTime
    },
    // 保存录音数据到数据库
    saveRecord(params) {
      console.log(params)
      saveRecord(params).then(res => {
        console.log(res)
        if (res.code == 200) {
          this.$message({
            message: '录音保存成功',
            type: 'success'
          })

          setTimeout(() => {
            // 关闭录音，释放录音资源
            this.rec.close()
            this.rec = null
            location.reload()
            // // 页面数据重置
            // Object.assign(this.$data, this.$options.data.call(this))
            // this.getUser()
            // this.getList()
          }, 1500)
        }
      })
    }
  }
}
</script>

<style lang="scss" scoped>
.title {
  display: flex;
  align-items: center;
  justify-content: center;
  .el-button {
    margin-left: 10px;
  }
}
.visit-desc {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  margin-top: 10px;

  .visit-item {
    display: flex;
    align-items: center;

    .label {
      color: #555555;
    }

    .value {
      color: #007aff;
    }
  }

  .visit-item:not(:first-child) {
    margin-left: 10px;
  }
}
.select-user {
  margin-top: 10px;
}
.footer-box {
  width: 100%;
  bottom: 25%;
  position: fixed;

  .time-box {
    height: 80px;
    line-height: 80px;
    text-align: center;
  }

  .button-box {
    display: flex;
    align-items: center;
    justify-content: space-evenly;

    .cancel-box {
      color: #f0ad4e;
      text-align: center;
      width: 130px;
    }

    .play-box {
      width: 130px;
      height: 130px;
      border: 2px solid #c8c7cc;
      border-radius: 50%;
      display: flex;
      align-items: center;
      justify-content: center;
    }

    .confirm-box {
      color: #007aff;
      text-align: center;
      width: 130px;
    }
  }
}
</style>
